package com.lcb.rabbitmq.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lcb.rabbitmq.entity.Mail;
import com.lcb.rabbitmq.entity.MsgLog;
import com.lcb.rabbitmq.mapper.MsgLogMapper;
import com.lcb.rabbitmq.utils.MailUtil;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class MailConsumer {

    public static final String LOCK_KEY = "LOCK_KEY";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private MailUtil mailUtil;

    @Autowired
    private MsgLogMapper msgLogMapper;

    @RabbitListener(queues = "mail.queue")
    @RabbitHandler
    public void consumer(String msg, Channel channel, @Header(value = AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {
        System.out.println("文档消费消息:" + msg);
        String msgId = "";
        try {
            Mail mail = JSON.parseObject(msg, Mail.class);
            msgId = mail.getMsgId();
            Boolean ifAbsent = stringRedisTemplate.opsForValue().setIfAbsent(LOCK_KEY + msgId, msgId, 30, TimeUnit.SECONDS);
            if (ifAbsent) {
                boolean success = mailUtil.send(mail);
                if (success) {
                    MsgLog msgLog = new MsgLog();
                    msgLog.setMsgId(msgId);
                    msgLog.setUpdateTime(new Date());
                    msgLog.setStatus(3);
                    msgLogMapper.updateByPrimaryKeySelective(msgLog);
                } else {
                    throw new Exception("send mail error");
                }
            } else {
                log.warn("请不要重复消费消息{}", msg);
            }
            channel.basicAck(tag, false);
            log.info("成功签收");
        } catch (Exception e) {
            e.printStackTrace();
            MsgLog msgLog = new MsgLog();
            msgLog.setMsgId(msgId);
            msgLog.setUpdateTime(new Date());
            msgLog.setStatus(4);
            msgLogMapper.updateByPrimaryKeySelective(msgLog);
            stringRedisTemplate.delete(LOCK_KEY + msgId);
            try {
                channel.basicNack(tag, false, true);
                log.info("拒绝签收");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            throw new Exception("send mail error");
        }
    }
}
